package nachos.network;

import nachos.machine.*;
import nachos.threads.*;
import nachos.userprog.*;
import nachos.vm.*;

/**
 * A <tt>VMProcess</tt> that supports networking syscalls.
 */
public class NetProcess extends UserProcess {
    /**
     * Allocate a new process.
     */
    public NetProcess() {
	super();
    }

    private static final int
	syscallConnect = 11,
	syscallAccept = 12;
    
    /**
     * Handle a syscall exception. Called by <tt>handleException()</tt>. The
     * <i>syscall</i> argument identifies which syscall the user executed:
     *
     * <table>
     * <tr><td>syscall#</td><td>syscall prototype</td></tr>
     * <tr><td>11</td><td><tt>int  connect(int host, int port);</tt></td></tr>
     * <tr><td>12</td><td><tt>int  accept(int port);</tt></td></tr>
     * </table>
     * 
     * @param	syscall	the syscall number.
     * @param	a0	the first syscall argument.
     * @param	a1	the second syscall argument.
     * @param	a2	the third syscall argument.
     * @param	a3	the fourth syscall argument.
     * @return	the value to be returned to the user.
     */


    //Syscall Handlers++++++++++++++++++++++++++++++++++++++++++
    // these two functions handle the two ends of the socket.
    // A staic "post office" is in NetKernel (it's prety mcuh
    // a list of ports.  It will probably just get a binding to
    // data structures in post office.  It'll probably also want
    // to keep track ofsockets that is is listening and talking on.
    // i think itll open the port like a file and push it onto
    // the file list and returns a file descriptor
    //----------------------------------------------------------
    public int handleSyscallConnect(int host, int port){
		Lib.debug('l', "made it into connect syscall");
	    NetSocket sckt = new NetSocket(port);
		if(!sckt.connect(host, port)){
			Lib.debug('l', "couldnt connect - syscall");
			return -1;
		}
		int desc = getFileDescriptor();
		openFiles[desc] = sckt;
		return desc;
    }

    public int handleSyscallAccept(int port){
		Lib.debug('l', "made it into accept syscall");
	    NetSocket sckt = new NetSocket(port);
		if(!sckt.accept(port)){
			Lib.debug('l', "couldnt accept - syscall");
			return -1;
		}
		int desc = getFileDescriptor();
		openFiles[desc] = sckt;
		return desc;
    }
    //==========================================================

    //this should be good to go now ---
    public int handleSyscall(int syscall, int a0, int a1, int a2, int a3) {
	switch (syscall) {
		case syscallConnect:
			return handleSyscallConnect(a0, a1);
		case syscallAccept:
			return handleSyscallAccept(a0);
	default:
	    return super.handleSyscall(syscall, a0, a1, a2, a3);
	}
    }
    //---------------------------------
}
